/**
 *  Version:     @(#)aio_socket.h    0.2.12 28/09/2006
 *
 *  Authors:     Hailong Xia <hlxxxx@gmail.com>
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty
 *  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
 *  the GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General
 *  Public License along with this library; if not, write to the
 *  Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 *  Boston, MA 02111-1307  USA
 */

#ifndef __AIO_SOCKET_H
#define __AIO_SOCKET_H

#ifdef HAVE_CONFIG_H
#include "aio_config.h"
#endif

#ifdef _WIN32
# define errnum WSAGetLastError()
# define EWOULDBLOCK WSAEWOULDBLOCK
# define ECONNRESET WSAECONNRESET
#else
# define closesocket(x) close(x)
# define errnum errno
#endif

#ifdef __cplusplus
extern "C" {
#endif

/* Success return !0, Fail return 0 */
int is_ip_addr(int af, const char *addr); 

#ifdef _WIN32
int inet_pton(int af, const char * src, void * dst);
const char * inet_ntop(int af, void const *src, char *dst, size_t size);
#endif

/* Success return 0, Fail return -1 */
int set_socket_blocking(int fd);

/* Success return 0, Fail return -1 */
int set_socket_nonblocking(int fd);

/* Success return 0, Fail return -1 */
int get_socket_ttl(int fd, int *ttl);

/* Success return 0, Fail return -1 */
int set_socket_ttl(int fd, int ttl);

/**
 * keepalive : on/off tcp keepalive
 * keepidle  : time that system idle to start detect
 * keepintvl : time interval per detect
 * keepcnt   : times that detect fail 
 * Success return 0, Fail return -1
 */
int set_tcp_keepalive(int fd, int keepalive,
        int keepidle, int keepintvl, int keepcnt);

/**
 * This function only support AF_INET proto family 
 * Don't support RAW socket 
 * Success return fd(>0), Fail return -1
 */
int create_socket(int servicetype, int prototype, int blocking);

/**
 * Success return 0, Fail return -1
 */
int bind_socket(int fd, unsigned long ip,
        unsigned short port, int reuse);

/**
 * blocking  : whether connection fd is blocking.
 * Success return connfd (>0), Fail return -1 
 * Wouldblock return 0
 */
int tcp_accept(int fd, unsigned long *frmip, 
        unsigned short *frmport, int blocking);

/** 
 * Block fd only return success or fail.
 * Success return fd(>0), Fail return -1 
 * Wouldblock return 0
 */
int tcp_connect(int fd, unsigned long ip, unsigned short port);

/**
 * Success return nbytes(>0), Fail return -1 
 * Wouldblock return 0
 */
int tcp_recv(int fd, char *buf, int len);

/**
 * Success return nbytes(>0), Fail return -1 
 * Wouldblcok return 0
 */
int tcp_send(int fd, const char *data, int len);

/* Success return 0, Fail return -1 */
int udp_connect(int fd, const char* ip, unsigned short port);

#ifdef _AIO_USE_OPENSSL /* OPENSSL 3.0 or TLS 1.0 */

#include <openssl/ssl.h>

/* Only for server, Success return 0, Fail return -1 */
int ssl_server_init(SSL_CTX **ctx, const char *cacrt, 
        const char *srvcrt, const char *srvkey);

/* Only for client, Success return 0, Fail return -1 */
int ssl_client_init(int fd, SSL_CTX **ctx, SSL **ssl);

/* Success return 0, Fail return -1 */
SSL* ssl_alloc(SSL_CTX *ctx, int fd);

/* Only for server, Success return > 0, Fail return -1 */
int ssl_accept(SSL *ssl);

/* Only for client, Success return 0, Fail return -1 */
int ssl_connect(SSL* ssl);

/* Success return > 0, Fail return -1 */
int ssl_recv(SSL *ssl, char *buf, int len);

/* Success return > 0, Fail return -1 */
int ssl_send(SSL *ssl, const char *data, int len);

#endif /* _AIO_USE_OPENSSL */

#ifdef __cplusplus
}
#endif

#endif /* __AIO_SOCKET_H */
